package com.zhj.process.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.MapType;

import org.springframework.util.Assert;

import java.io.IOException;
import java.util.Map;

/**
 * json工具类
 */
@SuppressWarnings("all")
public class JacksonUtils {
    /** objectMapper */
    private final static ObjectMapper objectMapper = new ObjectMapper();
    /** EMPTY_ARRAY */
    public static final byte[] EMPTY_ARRAY = new byte[0];
    /** MESSAGE */
    private static final String MESSAGE = "待解析的数据为空";

    /**
     * Jackson utils
     *
     * @since 1.0.0
     */
    private JacksonUtils() {
    }

    /**
     * Gets instance *
     *
     * @return the instance
     * @since 1.0.0
     */
    public static ObjectMapper getInstance() {
        return objectMapper;
    }

    /**
     * Parse
     *
     * @param <T>       parameter
     * @param content   content
     * @param valueType value type
     * @return the t
     * @since 1.0.0
     */
    public static <T> T parse(byte[] content, Class<T> valueType) {
        return parse(getInstance(), content, valueType);
    }

    /**
     * Parse
     *
     * @param <T>       parameter
     * @param mapper    mapper
     * @param content   content
     * @param valueType value type
     * @return the t
     * @since 1.0.0
     */
    public static <T> T parse(ObjectMapper mapper, byte[] content, Class<T> valueType) {
        if (Void.class.getTypeName().equals(valueType.getTypeName())) {
            return null;
        } else {
            Assert.notNull(content, "待解析的数据为空");
            try {
                return mapper.readValue(content, valueType);
            } catch (IOException var4) {
                throw new RuntimeException(var4);
            }
        }
    }

    /**
     * Parse
     *
     * @param <T>        parameter
     * @param jsonString json string
     * @param valueType  value type
     * @return the t
     * @since 1.0.0
     */
    public static <T> T parse(String jsonString, Class<T> valueType) {
        return parse(getInstance(), jsonString, valueType);
    }

    /**
     * Parse
     *
     * @param <T>        parameter
     * @param mapper     mapper
     * @param jsonString json string
     * @param valueType  value type
     * @return the t
     * @since 1.0.0
     */
    public static <T> T parse(ObjectMapper mapper, String jsonString, Class<T> valueType) {
        Assert.hasLength(jsonString, "待解析的数据为空");
        try {
            if (isJson(mapper, jsonString)) {
                return mapper.readValue(jsonString, valueType);
            }
            return (T) jsonString;
        } catch (IOException var4) {
            throw new RuntimeException(var4);
        }
    }

    /**
     * To json as bytes
     *
     * @param object object
     * @return the byte [ ]
     * @since 1.0.0
     */
    public static byte[] toJsonAsBytes(Object object) {
        return toJsonAsBytes(getInstance(), object);
    }

    /**
     * To json as bytes
     *
     * @param mapper mapper
     * @param object object
     * @return the byte [ ]
     * @since 1.0.0
     */
    public static byte[] toJsonAsBytes(ObjectMapper mapper, Object object) {
        if (object == null) {
            return EMPTY_ARRAY;
        } else {
            try {
                return mapper.writeValueAsBytes(object);
            } catch (JsonProcessingException var3) {
                throw new RuntimeException(var3);
            }
        }
    }

    /**
     * To json
     *
     * @param object object
     * @return the string
     * @since 1.0.0
     */
    public static String toJson(Object object) {
        return toJson(getInstance(), object, false, false);
    }

    /**
     * To json
     *
     * @param mapper mapper
     * @param object object
     * @param pretty pretty
     * @param always always
     * @return the string
     * @since 1.0.0
     */
    public static String toJson(ObjectMapper mapper, Object object, boolean pretty, boolean always) {
        if (object == null) {
            return "{}";
        } else {
            String json;
            if (object instanceof String) {
                json = StringUtils.trimWhitespace((String)object);
                if (!isJson(mapper, json)) {
                    return json;
                }
                object = parse(json, Object.class);
            }
            try {
                if (always) {
                    mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
                } else {
                    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                }

                if (pretty) {
                    json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
                } else {
                    json = mapper.writeValueAsString(object);
                }

                return json;
            } catch (JsonProcessingException var5) {
                throw new RuntimeException(var5);
            }
        }
    }

    /**
     * 判断是否是json字符串
     *
     * @param mapper       mapper
     * @param jsonInString json in string
     * @return boolean
     * @since 1.0.0
     */
    public static boolean isJson(ObjectMapper mapper, String jsonInString) {
        if (StringUtils.isEmpty(jsonInString)) {
            return false;
        } else {
            try {
                jsonInString = StringUtils.trimAllWhitespace(jsonInString);
                try {
                    mapper.readValue(jsonInString, getMapType(mapper, String.class, Object.class));
                } catch (Exception var3) {
                    mapper.readValue(jsonInString, Object[].class);
                }
                return true;
            } catch (IOException var4) {
                return false;
            }
        }
    }

    /**
     * 获取map key value类型
     *
     * @param mapper     mapper
     * @param keyClass   key class
     * @param valueClass value class
     * @return map type
     * @since 1.0.0
     */
    public static MapType getMapType(ObjectMapper mapper, Class<?> keyClass, Class<?> valueClass) {
        return mapper.getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
    }
}
